home *** CD-ROM | disk | FTP | other *** search
/ Aminet 35 / Aminet 35 (2000)(Schatztruhe)[!][Feb 2000].iso / Aminet / gfx / misc / gnuplot-src.lha / gnuplot-3.7.1src / gnuplot-3.7.1.lha / gnuplot-3.7.1 / os2 / print.c < prev   
Encoding:
C/C++ Source or Header  |  1998-12-18  |  17.9 KB  |  537 lines

  1. #ifdef INCRCy( pdriv,„GÃr RCSid[]="$Id: print.c,v 1.3 1998/12/17 22:10:44 lhecking Exp $" ;
  2. #endif
  3.  
  4. /****************************************************************************
  5.  
  6.     PROGRAM: gnupmdrv
  7.     
  8.     Outboard PM driver for GNUPLOT 3.3
  9.  
  10.     MODULE:  print.c -- support for printing graphics under OS/2 
  11.         
  12. ****************************************************************************/
  13.  
  14. /* PM driver for GNUPLOT */
  15.  
  16. /*[
  17.  * Copyright 1992, 1993, 1998 Roger Fearick
  18.  *
  19.  * Permission to use, copy, and distribute this software and its
  20.  * documentation for any purpose with or without fee is hereby granted,
  21.  * provided that the above copyright notice appear in all copies and
  22.  * that both that copyright notice and this permission notice appear
  23.  * in supporting documentation.
  24.  *
  25.  * Permission to modify the software is granted, but not the right to
  26.  * distribute the complete modified source code.  Modifications are to
  27.  * be distributed as patches to the released version.  Permission to
  28.  * distribute binaries produced by compiling modified sources is granted,
  29.  * provided you
  30.  *   1. distribute the corresponding source modifications from the
  31.  *    released version in the form of a patch file along with the binaries,
  32.  *   2. add special version identification to distinguish your version
  33.  *    in addition to the base release version number,
  34.  *   3. provide your name and address as the primary contact for the
  35.  *    support of your modified version, and
  36.  *   4. retain our contact information in regard to use of the base
  37.  *    software.
  38.  * Permission to distribute the released version of the source code along
  39.  * with corresponding source modifications in the form of a patch file is
  40.  * granted with same provisions 2 through 4 for binary distributions.
  41.  *
  42.  * This software is provided "as is" without express or implied warranty
  43.  * to the extent permitted by applicable law.
  44. ]*/
  45.  
  46. /*
  47.  * AUTHOR
  48.  * 
  49.  *   Gnuplot driver for OS/2:  Roger Fearick
  50.  * 
  51.  * Send your comments or suggestions to 
  52.  *  info-gnuplot@dartmouth.edu.
  53.  * This is a mailing list; to join it send a note to 
  54.  *  majordomo@dartmouth.edu.  
  55.  * Send bug reports to
  56.  *  bug-gnuplot@dartmouth.edu.
  57. **/
  58.  
  59. #define INCL_SPLDOSPRINT
  60. #define INCL_DOSPROCESS
  61. #define INCL_DOSSEMAPHORES
  62. #define INCL_DEV
  63. #define INCL_SPL
  64. #define INCL_PM
  65. #define INCL_WIN
  66. #include <os2.h>
  67. #include <stdio.h>
  68. #include <stdlib.h>
  69. #include <string.h>
  70. #include <process.h>
  71. #include "gnupmdrv.h"
  72.  
  73. #define   GNUPAGE   4096        /* size of gnuplot page in pixels (driver dependent) */
  74.  
  75.  
  76. typedef struct {            /* for print thread parameters */
  77.     HWND  hwnd ;
  78.     HDC   hdc ;                 /* printer device context */
  79.     HPS   hps ;                 /* screen PS to be printed */
  80.     char  szPrintFile[256] ;    /* file for printer output if not to printer */
  81.     PQPRINT pqp ;       /* print queue info */
  82.     } PRINTPARAMS ;
  83.  
  84. static struct { 
  85.     long    lTech ;     // printer technology
  86.     long    lVer ;      // driver version
  87.     long    lWidth ;    // page width in pels
  88.     long    lHeight ;   // page height in pels
  89.     long    lWChars ;   // page width in chars    
  90.     long    lHChars ;   // page height in chars    
  91.     long    lHorRes ;   // horizontal resolution pels / metre
  92.     long    lVertRes ;  // vertical resolution pels / metre
  93.     } prCaps ;
  94.  
  95. //static PDRIVDATA    pdriv = NULL ;
  96. static DRIVDATA     driv = {sizeof( DRIVDATA) } ;
  97. static char         szPrintFile[CCHMAXPATHCOMP] = {0} ;
  98. static DEVOPENSTRUC devop ;
  99.  
  100. ULONG GetPrinters( PPRQINFO3 *, ULONG *  ) ;
  101. int FindPrinter( char *, PPRQINFO3  ) ;
  102. HMF     CopyToMetaFile( HPS ) ; 
  103. static void    ThreadPrintPage( ) ;
  104.  
  105. MPARAM PrintCmdProc( HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
  106. /*
  107. **  Handle messages for print commands for 1- and 2-d spectra
  108. ** (i.e for the appropriate 1-and 2-d child windows )
  109. */
  110.     {
  111.     static BYTE abStack[4096] ;  
  112.     static PRINTPARAMS tp ;
  113.     static char szBusy[] = "Busy - try again later" ;
  114.     static char szStart[] = "Printing started" ;
  115.     static HEV semPrint = 0L ;
  116.     static HWND hwndCancel = NULLHANDLE ;
  117.     char szTemp[32] ;
  118.     unsigned short lErr ;
  119.     PBYTE pStack = abStack;
  120.     TID tid ;
  121.     char *pszMess, *szPrinter ;
  122.  
  123.     if( semPrint == 0L ) {
  124.         DosCreateMutexSem( NULL, &semPrint, 0L, 0L ) ;
  125.         }
  126.  
  127.     switch( msg ) {
  128.         
  129.         case WM_USER_PRINT_BEGIN:
  130.         
  131.             if( DosRequestMutexSem( semPrint, SEM_IMMEDIATE_RETURN ) != 0 ) {
  132.                 pszMess = szBusy ;
  133.                 WinMessageBox( HWND_DESKTOP,
  134.                                hWnd, 
  135.                                pszMess,
  136.                                APP_NAME,
  137.                                0,
  138.                                MB_OK | MB_ICONEXCLAMATION ) ;
  139.                 }
  140.             else {
  141.                 pszMess = szStart ;
  142.                 tp.hwnd = hWnd ;
  143.                 tp.pqp = (PQPRINT) mp1 ;
  144.                 tp.hps = (HPS) mp2 ;
  145.                 strcpy( tp.szPrintFile, szPrintFile ) ;
  146.                 tid = _beginthread( ThreadPrintPage, NULL, 32768, &tp ) ;
  147.                 hwndCancel = WinLoadDlg( HWND_DESKTOP,
  148.                                          hWnd,
  149.                                          (PFNWP)CancelPrintDlgProc,
  150.                                          0L,
  151.                                          ID_PRINTSTOP,
  152.                                          NULL ) ; 
  153.                 }
  154.             break ;
  155.  
  156.  
  157.         case WM_USER_PRINT_OK :
  158.  
  159.             if( hwndCancel != NULLHANDLE ) {
  160.                 WinDismissDlg( hwndCancel, 0 ) ; 
  161.                 hwndCancel = NULLHANDLE ;
  162.                 }
  163.              DosReleaseMutexSem( semPrint ) ;
  164.              break ;
  165.  
  166.         case WM_USER_DEV_ERROR :
  167.  
  168.             if( hwndCancel != NULLHANDLE ) {
  169.                 WinDismissDlg( hwndCancel, 0 ) ; 
  170.                 hwndCancel = NULLHANDLE ;
  171.                 }
  172.             lErr = ERRORIDERROR( (ERRORID) mp1 ) ;
  173.             sprintf( szTemp, "Dev error: %d %x", lErr, lErr ) ;
  174.             WinMessageBox( HWND_DESKTOP,
  175.                            hWnd, 
  176.                            szTemp,
  177.                            APP_NAME,
  178.                            0,
  179.                            MB_OK | MB_ICONEXCLAMATION ) ;
  180.              DosReleaseMutexSem( semPrint ) ;
  181.              break ;
  182.  
  183.         case WM_USER_PRINT_ERROR :
  184.         
  185.             if( hwndCancel != NULLHANDLE ) {
  186.                 WinDismissDlg( hwndCancel, 0 ) ; 
  187.                 hwndCancel = NULLHANDLE ;
  188.                 }
  189.             lErr = ERRORIDERROR( (ERRORID) mp1 ) ;
  190.             sprintf( szTemp, "Print error: %d %x", lErr, lErr ) ;
  191.             WinMessageBox( HWND_DESKTOP,
  192.                            hWnd, 
  193.                            szTemp,
  194.                            APP_NAME,
  195.                            0,
  196.                            MB_OK | MB_ICONEXCLAMATION ) ;
  197.              DosReleaseMutexSem( semPrint ) ;
  198.              break ;
  199.  
  200.         case WM_USER_PRINT_CANCEL :
  201.  
  202.              DevEscape( tp.hdc, DEVESC_ABORTDOC, 0L, NULL, NULL, NULL ) ;
  203.              break ;
  204.  
  205.  
  206.         case WM_USER_PRINT_QBUSY :
  207.  
  208.             return( (MPARAM)DosRequestMutexSem( semPrint, SEM_IMMEDIATE_RETURN ) ) ;
  209.             
  210.         default : break ;
  211.         }
  212.         
  213.     return 0L ;
  214.     }
  215.  
  216. int SetupPrinter( HWND hwnd, PQPRINT pqp )
  217. /*
  218. **  Set up the printer
  219. **
  220. */
  221.     {
  222.     HDC hdc ;
  223.     float flXFrac, flYFrac;
  224.           /* check that printer is still around .. */
  225.     if( FindPrinter( pqp->szPrinterName, pqp->piPrinter ) != 0 ) return 0 ;
  226.           /* get printer capabilities */
  227.     if( (hdc = OpenPrinterDC( WinQueryAnchorBlock( hwnd ), pqp, OD_INFO, NULL )) != DEV_ERROR ) {
  228.         DevQueryCaps( hdc, CAPS_TECHNOLOGY, (long)sizeof(prCaps)/sizeof(long), (PLONG)&prCaps ) ;
  229.         DevCloseDC( hdc ) ;
  230.         pqp->xsize = (float)100.0* (float) prCaps.lWidth / (float) prCaps.lHorRes ; // in cm
  231.         pqp->ysize = (float)100.0* (float) prCaps.lHeight / (float) prCaps.lVertRes ; // in cm
  232.         flXFrac = pqp->xfrac ;
  233.         flYFrac = pqp->yfrac ;
  234.         pqp->szFilename[0] = 0 ;
  235.         szPrintFile[0] = 0 ;
  236.         pqp->caps  = prCaps.lTech & (CAPS_TECH_VECTOR_PLOTTER|CAPS_TECH_POSTSCRIPT) ?
  237.                    QP_CAPS_FILE : QP_CAPS_NORMAL ;        
  238.         if( WinDlgBox( HWND_DESKTOP,
  239.                       hwnd,
  240.                     (PFNWP)QPrintDlgProc,
  241.                     0L,
  242.                     ID_QPRINT,
  243.                     pqp ) == DID_OK ) {
  244.           if( pqp->caps & QP_CAPS_FILE ) {
  245.               if( pqp->szFilename[0] != 0 ) strcpy( szPrintFile, pqp->szFilename ) ;
  246.               }
  247.           return 1 ;
  248.           }    
  249.         pqp->xfrac = flXFrac ;
  250.         pqp->yfrac = flYFrac ;
  251.         }
  252.     
  253.     return 0 ;
  254.     }
  255.  
  256. int SetPrinterMode( HWND hwnd, PQPRINT pqp )
  257. /*
  258. **  call up printer driver's own setup dialog box
  259. **
  260. **  returns :  -1 if error
  261. **              0 if no settable modes
  262. **              1 if OK
  263. */
  264.     {
  265.     HAB hab ;
  266.     LONG lBytes ;
  267.     PPRQINFO3 pinfo = pqp->piPrinter ;
  268.  
  269.     hab = WinQueryAnchorBlock( hwnd ) ;
  270.     driv.szDeviceName[0]='\0' ;
  271.     lBytes = DevPostDeviceModes( hab,
  272.                                  NULL,
  273.                                  devop.pszDriverName,
  274.                                  pinfo->pDriverData->szDeviceName,
  275.                                  //driv.szDeviceName,
  276.                                  NULL,
  277.                                  DPDM_POSTJOBPROP ) ;
  278.     if( lBytes > 0L ) {
  279.             /* if we have old pdriv data, and if it's for the same printer,
  280.                keep it to retain user's current settings, else get new */
  281.         if( pqp->pdriv != NULL
  282.         && strcmp( pqp->pdriv->szDeviceName, pinfo->pDriverData->szDeviceName ) != 0 ) {
  283.             free( pqp->pdriv ) ;
  284.             pqp->pdriv = NULL ;
  285.             }
  286.         if( pqp->pdriv == NULL ) {
  287.             if( lBytes < pinfo->pDriverData->cb ) lBytes = pinfo->pDriverData->cb ;
  288.             pqp->pdriv = malloc( lBytes ) ;
  289.             pqp->cbpdriv = lBytes ;
  290.             memcpy( pqp->pdriv, pinfo->pDriverData, lBytes ) ;
  291.             }
  292.         strcpy( driv.szDeviceName, pqp->pdriv->szDeviceName ) ;
  293. //        pqp->pdriv->szDeviceName[0] = '\0' ;  /* to check if 'cancel' selected */
  294.         lBytes = DevPostDeviceModes( hab,
  295.                                      pqp->pdriv,
  296.                                      devop.pszDriverName,
  297.                                      driv.szDeviceName,
  298.                                      NULL,
  299.                                      DPDM_POSTJOBPROP ) ;
  300.         if( lBytes != 1 /*pqp->pdriv->szDeviceName[0] == '\0'*/ ) {  /* could be: 'cancel' selected */
  301.             pqp->cbpdriv = lBytes = 0 ;
  302.             free(pqp->pdriv ) ;   /* is this right ???? */
  303.             pqp->pdriv = NULL ;
  304.             }
  305.         }
  306.     return ( (int) lBytes ) ;
  307.     }
  308.  
  309. static void ThreadPrintPage( PRINTPARAMS *ptp )
  310. /*
  311. **  thread to set up printer DC and print page 
  312. **
  313. **  Input: THREADPARAMS *ptp -- pointer to thread data passed by beginthread
  314. **
  315. */
  316.     {    
  317.     HAB         hab ;       // thread anchor block nandle
  318.     HDC         hdc ;       // printer device context handle
  319.     HPS         hps ;       // presentation space handle
  320.     HDC         hdcOld ;    // old hdc associated with hps
  321.     SHORT       msgRet ;    // message posted prior to return (end of thread)
  322.     SIZEL       sizPage ;   // size of page for creation of presentation space
  323.     LONG        alPage[2] ; // actual size of printer page in pixels
  324.     RECTL       rectPage ;  // viewport on page into which we draw
  325.     LONG        lColors ;
  326.     char        *szPrintFile ;
  327.     HMF         hmf ;
  328.     LONG        alOpt[9] ;
  329.     HPS         hpsSc ;    
  330.     hab = WinInitialize( 0 ) ;
  331.     
  332.     szPrintFile = ptp->szPrintFile[0] == '\0' ? NULL : ptp->szPrintFile ;
  333.     
  334.     if( (hdc = OpenPrinterDC( hab, ptp->pqp, 0L, szPrintFile )) != DEV_ERROR ) {
  335.     
  336.             // create presentation space for printer
  337.  
  338.         ptp->hdc = hdc ;
  339.         hmf = CopyToMetaFile( ptp->hps ) ;
  340.         hpsSc = ptp->hps ;
  341.  
  342.         sizPage.cx = GNUXPAGE;
  343.         sizPage.cy = GNUYPAGE;
  344.         hps = GpiCreatePS( hab,
  345.                            hdc,
  346.                            &sizPage,
  347.                            PU_HIMETRIC | GPIF_DEFAULT | GPIT_NORMAL | GPIA_ASSOC ) ;
  348.  
  349.         DevQueryCaps( hdc, CAPS_WIDTH, 2L, alPage ) ;
  350.         DevQueryCaps( hdc, CAPS_PHYS_COLORS, 1L, &lColors ) ;
  351.         rectPage.xLeft = 0L ;
  352.         rectPage.xRight = alPage[0] ;
  353.         rectPage.yTop = alPage[1] ;//alPage[1]*(1.0-flYFrac) ;
  354.         rectPage.yBottom = 0L ; //  = alPage[1] ;
  355.        
  356.         {
  357.         double ratio = 1.560 ;
  358.         double xs = rectPage.xRight - rectPage.xLeft ;
  359.         double ys = rectPage.yTop - rectPage.yBottom ;
  360.         if( ys > xs/ratio ) { /* reduce ys to fit */
  361.             rectPage.yTop = rectPage.yBottom + (int)(xs/ratio) ; 
  362.             }
  363.         else if( ys < xs/ratio ) { /* reduce xs to fit */
  364.             rectPage.xRight = rectPage.xLeft + (int)(ys*ratio) ;
  365.             }
  366.         }
  367.        
  368.         rectPage.xRight = rectPage.xRight*ptp->pqp->xfrac ;
  369.         rectPage.yTop = rectPage.yTop*ptp->pqp->yfrac ;//alPage[1]*(1.0-flYFrac) ;
  370.  
  371.         {
  372.         double ratio = 1.560 ;
  373.         double xs = rectPage.xRight - rectPage.xLeft ;
  374.         double ys = rectPage.yTop - rectPage.yBottom ;
  375.         if( ys > xs/ratio ) { /* reduce ys to fit */
  376.             rectPage.yTop = rectPage.yBottom + (int)(xs/ratio) ; 
  377.             }
  378.         else if( ys < xs/ratio ) { /* reduce xs to fit */
  379.             rectPage.xRight = rectPage.xLeft + (int)(ys*ratio) ;
  380.             }
  381.         }
  382.  
  383.  
  384.             // start printing
  385.                     
  386.         if( DevEscape( hdc, 
  387.                        DEVESC_STARTDOC,
  388.                        7L,
  389.                        APP_NAME,
  390.                        NULL,
  391.                        NULL ) != DEVESC_ERROR ) {
  392.             char buff[256] ;
  393.             int rc;
  394.  
  395.             rc = GpiSetPageViewport( hps, &rectPage ) ;
  396.  
  397.             alOpt[0] = 0L ;
  398.             alOpt[1] = LT_ORIGINALVIEW ;
  399.             alOpt[2] = 0L ;
  400.             alOpt[3] = LC_LOADDISC ;
  401.             alOpt[4] = RES_DEFAULT ;
  402.             alOpt[5] = SUP_DEFAULT ;
  403.             alOpt[6] = CTAB_DEFAULT ;
  404.             alOpt[7] = CREA_DEFAULT ;
  405.             alOpt[8] = DDEF_DEFAULT ;
  406.             if (rc) rc=GpiPlayMetaFile( hps, hmf, 9L, alOpt, NULL, 255, buff ) ;
  407.  
  408.             if (rc) {
  409.               DevEscape( hdc, DEVESC_ENDDOC, 0L, NULL, NULL, NULL ) ;
  410.               msgRet = WM_USER_PRINT_OK ;
  411.               }
  412.             else
  413.               msgRet = WM_USER_PRINT_ERROR;
  414.               
  415.             }
  416.         else
  417.             msgRet = WM_USER_PRINT_ERROR ;
  418.         
  419.         GpiDestroyPS( hps ) ;
  420.         DevCloseDC( hdc ) ;
  421.         }
  422.     else
  423.         msgRet = WM_USER_DEV_ERROR ;
  424.         
  425.     DosEnterCritSec() ;
  426.     WinPostMsg( ptp->hwnd, msgRet, (MPARAM)WinGetLastError(hab), 0L ) ;
  427.     WinTerminate( hab ) ;
  428.     }
  429.  
  430. HDC OpenPrinterDC( HAB hab, PQPRINT pqp, LONG lMode, char *szPrintFile )
  431. /*
  432. ** get printer info from os2.ini and set up DC
  433. **
  434. ** Input:  HAB hab  -- handle of anchor block of printing thread
  435. **         PQPRINT-- pointer to data of current selected printer
  436. **         LONG lMode -- mode in which device context is opened = OD_QUEUED, OD_DIRECT, OD_INFO
  437. **         char *szPrintFile -- name of file for printer output, NULL
  438. **                  if to printer (only used for devices that support file
  439. **                  output eg plotter, postscript)
  440. **
  441. ** Return: HDC      -- handle of printer device context
  442. **                   = DEV_ERROR (=0) if error
  443. */
  444.     {
  445.     CHAR   *pchDelimiter ;
  446.     LONG   lType ;
  447.     static CHAR   achPrinterData[256] ;
  448.  
  449.     if( pqp->piPrinter == NULL ) return DEV_ERROR ;
  450.         
  451.     strcpy( achPrinterData, pqp->piPrinter->pszDriverName ) ;
  452.     achPrinterData[ strcspn(achPrinterData,".") ] = '\0' ;
  453.  
  454.     devop.pszDriverName = achPrinterData ;
  455.     devop.pszLogAddress = pqp->piPrinter->pszName ;
  456.  
  457.     if( pqp->pdriv != NULL 
  458.         && strcmp( pqp->pdriv->szDeviceName, pqp->piPrinter->pDriverData->szDeviceName ) == 0 ) {
  459.         devop.pdriv = pqp->pdriv ;
  460.         }
  461.     else devop.pdriv = pqp->piPrinter->pDriverData ;
  462.  
  463.     if( szPrintFile != NULL )  devop.pszLogAddress = szPrintFile ;
  464.         
  465.             // set data type to RAW
  466.             
  467.     devop.pszDataType = "PM_Q_RAW" ;
  468.     
  469.             // open device context
  470.     if( lMode != 0L ) 
  471.         lType = lMode ;
  472.     else
  473.         lType = (szPrintFile == NULL) ? OD_QUEUED: OD_DIRECT ;
  474.  
  475.     return DevOpenDC( hab, //  WinQueryAnchorBlock( hwnd ),
  476.                       lType,
  477.                       "*",
  478.                       4L,
  479.                       (PDEVOPENDATA) &devop,
  480.                       NULLHANDLE ) ;
  481.     }
  482.  
  483. int FindPrinter( char *szName, PPRQINFO3 piPrinter )
  484. /*
  485. **  Find a valid printer
  486. */
  487.     {
  488.     PPRQINFO3 pprq = NULL ;
  489.     PDRIVDATA pdriv = NULL ;
  490.     LONG np ;
  491.     
  492.     if( *szName && (strcmp( szName, piPrinter->pszName ) == 0) ) return 0 ;
  493.     if( GetPrinters( &pprq , &np ) == 0 ) return 1 ;
  494.     for( --np; np>=0; np-- ) {
  495.         if( strcmp( szName, pprq[np].pszName ) == 0 ) {
  496.             if( piPrinter->pDriverData != NULL ) free( piPrinter->pDriverData ) ;
  497.             pdriv = malloc( pprq[np].pDriverData->cb ) ;
  498.             memcpy( piPrinter, &pprq[np], sizeof( PRQINFO3 ) ) ;
  499.             piPrinter->pDriverData = pdriv ;
  500.             memcpy( pdriv, pprq[np].pDriverData, pprq[np].pDriverData->cb ) ;
  501.             free( pprq ) ;
  502.             return 0 ;
  503.             }
  504.         }
  505.     memcpy( piPrinter, &pprq[0], sizeof( PRQINFO3 ) ) ;
  506.     free( pprq ) ;
  507.     return 0 ;
  508.     }
  509.  
  510. MRESULT EXPENTRY CancelPrintDlgProc ( HWND hwnd, ULONG usMsg, MPARAM mp1, MPARAM mp2 )
  511. /*
  512. **  Cancel printing dialog box proc
  513. */
  514.     {
  515.     switch ( usMsg ) {
  516.  
  517.         case WM_COMMAND :
  518.             switch ( SHORT1FROMMP(mp1) ) {
  519.                 case DID_CANCEL:
  520.                     WinSendMsg( WinQueryWindow( hwnd, QW_OWNER ),
  521.                                     WM_USER_PRINT_CANCEL,
  522.                                     0L,
  523.                                     0L ) ;
  524.                     WinDismissDlg( hwnd, 0 ) ; 
  525.                     break ;
  526.                 default:
  527.                     break ;
  528.                 }
  529.         default:
  530.             break ;
  531.         }
  532.         /* fall through to the default control processing */
  533.     return WinDefDlgProc ( hwnd , usMsg , mp1 , mp2 ) ;
  534.     }
  535.     
  536.  
  537.